/**
 * Copyright (c) 2018-2099, Chill Zhuang 庄骞 (bladejava@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springblade.modules.restaurant.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.restaurant.entity.OperatingIncome;
import org.springblade.modules.restaurant.mapper.OperatingIncomeMapper;
import org.springblade.modules.restaurant.service.*;
import org.springblade.modules.restaurant.vo.OperatingIncomeVO;
import org.springblade.modules.system.service.ITenantService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * 营业收入表 服务实现类
 *
 * @author Blade
 * @since 2025-02-05
 */
@AllArgsConstructor
@Service
public class OperatingIncomeServiceImpl extends BaseServiceImpl<OperatingIncomeMapper, OperatingIncome> implements IOperatingIncomeService {
	private ITenantService tenantService;
	private IUserSalaryDayService userSalaryDayService;
	private ICommoditySummaryService commoditySummaryService;
	private IExpensesBudgetService expensesBudgetService;
	private IExpensesCostService expensesCostService;

	@Override
	public IPage<OperatingIncomeVO> selectOperatingIncomePage(IPage<OperatingIncomeVO> page, OperatingIncomeVO operatingIncome) {
		return page.setRecords(baseMapper.selectOperatingIncomePage(page, operatingIncome));
	}

	@Override
	public BigDecimal getOperatingIncomeMonthSum(String businessTime, String tenantId) {
		String startTime = DateUtil.formatDate(DateUtil.beginOfMonth(DateUtil.parse(businessTime)));
		String endTime = DateUtil.formatDate(DateUtil.endOfMonth(DateUtil.parse(businessTime)));
		List<OperatingIncome> operatingIncomeList = list(Wrappers.<OperatingIncome>lambdaQuery()
			.ge(OperatingIncome::getOperatingTime, startTime)
			.le(OperatingIncome::getOperatingTime, endTime)
			.eq(OperatingIncome::getTenantId, tenantId)
		);
		BigDecimal sum = BigDecimal.ZERO;
		for (OperatingIncome operatingIncome : operatingIncomeList) {
			sum = sum.add(operatingIncome.getTotalIncome());
		}
		return sum;
	}


	@Override
	public void calculateOperatingIncome(String time) {
		List<String> tenantIds = tenantService.getAllTenantIds();
		for (String tenantId : tenantIds) {
			OperatingIncome operatingIncome = lambdaQuery().eq(OperatingIncome::getOperatingTime, time).eq(OperatingIncome::getTenantId, tenantId).one();
			if (operatingIncome == null) {
				operatingIncome = new OperatingIncome();
				operatingIncome.setOperatingTime(time);
				operatingIncome.setTenantId(tenantId);
			}
			calculate(operatingIncome, time, tenantId);
		}
	}

	@Override
	public boolean calculate(OperatingIncome operatingIncome, String time, String tenantId) {
		// 薪资支出
		BigDecimal userSalarySum = userSalaryDayService.userSalaryDaySum(time, tenantId);
		operatingIncome.setSalaryExpenses(userSalarySum);

		// 判断是否为当月 当月的话
		boolean isSameMonth = DateUtil.isSameMonth(DateUtil.parse(time), DateUtil.date());
		// 预算日平均费用
		BigDecimal expensesBudgetSum = BigDecimal.ZERO;

		if (isSameMonth) {
			// 预算支出
			expensesBudgetSum = expensesBudgetService.getExpensesBudgetDayAvg(time, tenantId);
		}
		operatingIncome.setFixedExpenses(expensesBudgetSum);

		// 费用支出
		BigDecimal expensesCostSum = expensesCostService.getExpensesCostDaySum(time, tenantId);
		operatingIncome.setOtherExpenses(expensesCostSum);

		// 采购支出
		BigDecimal commoditySummarySum = commoditySummaryService.getCommoditySummaryDaySum(time, tenantId);
		operatingIncome.setProcurementExpenses(commoditySummarySum);

		// 计算当月数据时： 总支出 = 薪资支出 + 预算支出 + 费用支出 + 采购支出
		// 计算非当月数据时： 总支出 = 薪资支出 + 费用支出 + 采购支出
		BigDecimal expendAmount = userSalarySum.add(expensesCostSum).add(commoditySummarySum).add(expensesBudgetSum);
		operatingIncome.setExpendAmount(expendAmount);

		// 营业收入
		BigDecimal incomeAmount = operatingIncome.getTotalIncome() == null ? BigDecimal.ZERO : operatingIncome.getTotalIncome();

		// 营业毛利 = 营业收入 - 采购支出 - 费用支出
		BigDecimal profitAmount = incomeAmount.subtract(commoditySummarySum).subtract(expensesCostSum);
		operatingIncome.setProfitAmount(profitAmount);

		// 营业净利 = 营业收入 - 采购支出 - 费用支出 - 预算支出 - 薪资支出 = 营业收入 - 总支出
		operatingIncome.setNetProfit(incomeAmount.subtract(expendAmount));

		return saveOrUpdate(operatingIncome);
	}

}
